package code.rocky.chapter07;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;

public class DecorateAnimal implements Animal {

    // 被包装的动物
    private Animal animal;

    private Class<? extends Feature> clz;

    public DecorateAnimal(Animal _animal, Class<? extends Feature> _clz) {
        animal = _animal;
        clz    = _clz;
    }

    @Override
    public void doStuff() {
        InvocationHandler handler = new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object obj = null;
                if (Modifier.isPublic(method.getModifiers())) {
                    obj = method.invoke(clz.newInstance(), args);
                }
                animal.doStuff();
                return obj;
            }
        };
        // 当前加载器
        ClassLoader c1 = getClass().getClassLoader();
        // 动态代理, 由 Handler 决定如何包装
        Feature proxy = (Feature) Proxy.newProxyInstance(c1, clz.getInterfaces(), handler);
        proxy.load();
    }

    public static void main(String[] args) {
        Animal Jerry = new Rat();
        // 增加一只翅膀
        Jerry = new DecorateAnimal(Jerry, FlyFeature.class);
        // 增加钻地能力
        Jerry = new DecorateAnimal(Jerry, DigFeature.class);
        Jerry.doStuff();
    }
}
